﻿using System.Threading;
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.IO;
using System.Text.RegularExpressions;
using TravianHelper.hero;
using TravianHelper.app;
using TravianHelper.village;

namespace TravianHelper
{
    public partial class Form2 : Form
    {

        TravianApplicationContext context = new TravianApplicationContext();

        public Form2()
        {
            InitializeComponent();
        }

        public void reloadComboBoxVillage()
        {
            comboBoxVillage.Items.Clear();
            for (int i = 0; i < TravianApplicationContext.villages.Count; i++)
            {
                Village village = (Village)TravianApplicationContext.villages[i];
                comboBoxVillage.Items.Add(village.name);
            }
        }


        private void buttonLogin_Click(object sender, EventArgs e)
        {
            TravianApplicationContext.adapter.username1 = textBoxUsername.Text;
            TravianApplicationContext.adapter.username2 = textBoxUsername2.Text;
            TravianApplicationContext.adapter.password1 = textBoxPassword.Text;
            TravianApplicationContext.adapter.password2 = textBoxPassword2.Text;
            if (TravianApplicationContext.loggedIn == false)
            {
                if (TravianApplicationContext.adapter.login())
                {
                    TravianApplicationContext.adapter.login2();
                    TravianApplicationContext.loggedIn = true;
                    buttonLogin.Text = "logout";
                    buttonStart.Enabled = true;
                    TravianApplicationContext.loadData();
                    updateListViewTarget(TravianApplicationContext.oasis);
                    UpdateListViewFarmList(TravianApplicationContext.farmlists);
                    reloadComboBoxVillage();

                    MessageBox.Show("Logged in successful");
                }
                else
                {
                    MessageBox.Show("Log in failed");
                }
            }
            else
            {
                TravianApplicationContext.adapter.logout();
            }
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            TravianApplicationContext.mainForm = this;
            reloadComboBoxVillage();
        }

        private void buttonAddVillage_Click(object sender, EventArgs e)
        {
            Village village = new Village();
            village.name = comboBoxVillage.Text;
            TravianApplicationContext.villages.Add(village);
            reloadComboBoxVillage();
        }

        private void buttonRemoveVillage_Click(object sender, EventArgs e)
        {
            int i = comboBoxVillage.SelectedIndex;
            Village village = (Village)TravianApplicationContext.villages[i];
            string name = village.name;
            if (MessageBox.Show("Do you want to remove village \"" + name + "\" ?", "Travian Helper",
         MessageBoxButtons.YesNo, MessageBoxIcon.Question)
         == DialogResult.Yes)
            {
                TravianApplicationContext.villages.RemoveAt(comboBoxVillage.SelectedIndex);
                reloadComboBoxVillage();
            }
        }

        private void comboBoxVillage_SelectedIndexChanged(object sender, EventArgs e)
        {
            int i = comboBoxVillage.SelectedIndex;
            Village village = (Village)TravianApplicationContext.villages[i];
            VillageForm villageForm = new VillageForm(false);
            villageForm.setVillage(village);
            villageForm.Show();


        }

        private void buttonSave_Click(object sender, EventArgs e)
        {
            int i = comboBoxVillage.SelectedIndex;
            Village village = (Village)TravianApplicationContext.villages[i];

            reloadComboBoxVillage();
            comboBoxVillage.SelectedIndex = i;
        }


        private void Form2_FormClosing(object sender, FormClosingEventArgs e)
        {
            saveAll();
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            if (timer1.Enabled)
            {
                buttonStart.Text = "Start";
                timer1.Stop();
                backgroundWorker3.CancelAsync();
            }
            else
            {
                timer1.Interval = Convert.ToInt32(textBoxInterval.Text) * 1000;
                buttonStart.Text = "Stop";
                saveAll();
                //backgroundWorker2.RunWorkerAsync();
                timer1.Start();
                backgroundWorker3.RunWorkerAsync();
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            backgroundWorker3.RunWorkerAsync();
        }

        bool processing = false;
        int lid = 0;
        private void doTick2()
        {
            if (!processing && TravianApplicationContext.farmlists.Count > 0)
            {
                processing = true;
                FarmList farmlist = (FarmList)TravianApplicationContext.farmlists[lid];
                int eid = farmlist.count;
                do
                {
                    eid = TravianApplicationContext.adapter.activateFarmlist(farmlist.id, farmlist.count, farmlist.vid.ToString(), farmlist.trooptype);
                    if (eid == -2)
                    {
                        Console.WriteLine("banned temporary. logout");
                        TravianApplicationContext.adapter.logout();
                        bool loggin = false;
                        do
                        {
                            loggin = TravianApplicationContext.adapter.login();
                        } while (loggin == false);
                        Console.WriteLine("logged back in");
                    }
                } while (eid < 0);
                lid = (lid+1) % TravianApplicationContext.farmlists.Count;
                if (eid >= 0)
                {
                    farmlist.count = eid;
                }
                Console.WriteLine("Timer done at: "+ lid + " " + eid);
                UpdateListViewFarmList(TravianApplicationContext.farmlists);
                processing = false;
                
            }
        }

        private void doTick3() // New oasis farming
        {
            if (!processing)
            {
                processing = true;
                try
                {
                    // for each village
                    for (int j = 0; j < TravianApplicationContext.villages.Count; j++)
                    {
                        Village village = (Village)TravianApplicationContext.villages[j];
                        TravianApplicationContext.heroInfo = TravianApplicationContext.heroManager.loadHeroInfo();

                        HeroInfo hero = TravianApplicationContext.heroInfo;
                        HeroConfig heroConfig = TravianApplicationContext.heroConfig;
                        // do adventure
                        if (hero.health >= heroConfig.minHealthWithTroop && hero.available && heroConfig.autoAdventure)
                        {
                            bool adventure = TravianApplicationContext.adapter.adventure();
                            if (adventure) hero.available = false;
                        }
                        // solo oasis
                        if (hero.health >= heroConfig.minHealthSolo && hero.available && heroConfig.clearOasisSolo)
                        {
                            ArrayList tmp = village.oasis;
                            village.oasis.Sort(new ZoneComparer());
                            for (int k = 0; k < village.oasis.Count; k++)
                            {
                                Zone zone = (Zone)village.oasis[k];
                                int def = TravianApplicationContext.adapter.getOasisDefend(zone.x, zone.y, false);
                                zone.defend = def;
                                if (def == 0)
                                {
                                    zone.status = "Def " + def + ", pass";
                                }
                                else if (def < hero.fighting / heroConfig.soloFightingTimes)
                                {
                                    String result = TravianApplicationContext.adapter.attack(zone.x, zone.y, 1, 0, village.id, true);
                                    zone.status = result;
                                    Util.SerializeArrayList(TravianApplicationContext.villages, "villages.xml");
                                    if (result.StartsWith("Troop sent"))
                                    {
                                        listViewLog.Items.Add("Solo oasis " + zone.x + " " + zone.y);
                                        hero.available = false;
                                        break;
                                    }
                                }
                                else
                                {
                                    zone.status = "Oasis defend too strong";
                                }
                            }
                            village.oasis = tmp;
                        }
                        // for each type of troop
                        for (int i = 0; i < village.troops.Count; i++)
                        {
                            Troop troop = (Troop)village.troops[i];
                            int id = troop.id;
                            string name = troop.name;
                            int nEachWave = troop.number_each_wave;
                            int minTroopEachWave = troop.minNumberEachWave;
                            int troopStay = troop.stay;
                            VillageInfo info = TravianApplicationContext.adapter.getVillageInfo(village.id);
                            int troopcount = info.getTroopCount(name);

                            if (troop.number_each_wave >= 1)
                            {
                                Console.WriteLine("Sending "+name);
                                while (troopcount >= nEachWave)
                                {
                                    if (village.current >= village.oasis.Count) village.current = 0;
                                    if (DateTime.Now.Ticks / 10000000 - village.lastSent > 3600)
                                    {
                                        Console.WriteLine("1h from last sent, reset: " + DateTime.Now.Ticks / 10000000);
                                        village.lastSent = DateTime.Now.Ticks / 10000000;
                                        village.current = 0;
                                    }
                                    Zone zone = (Zone)village.oasis[village.current];
                                    int def = TravianApplicationContext.adapter.getOasisDefend(zone.x, zone.y, TravianApplicationContext.heroConfig.infantry);
                                    zone.defend = def;
                                    String result = "";
                                    bool sent = false;
                                    if (def == 0)
                                    {
                                        // sending troop in ramdom number
                                        TravianApplicationContext.adapter.selectCity(village.id, name);
                                        Int32 troopToGo = new Random().Next(minTroopEachWave, nEachWave + 1);
                                        result = TravianApplicationContext.adapter.attack(zone.x, zone.y, troop.id, troopToGo, village.id, false);
                                        zone.status = result;
                                        Util.SerializeArrayList(TravianApplicationContext.villages, "villages.xml");
                                        Console.WriteLine("sent " + troopToGo + " of " + name + " to " + zone.x + "|" + zone.y);
                                        sent = true;
                                    }
                                    else
                                    {
                                        if (def < troop.stay)
                                        {
                                            int troopToGo = def * 10 / troop.attack;
                                            if (troopToGo < troopcount)
                                            {
                                                result = TravianApplicationContext.adapter.attack(zone.x, zone.y, troop.id, troopToGo, village.id, false);
                                                zone.status = result;
                                                Util.SerializeArrayList(TravianApplicationContext.villages, "villages.xml");
                                                Console.WriteLine("sent " + troopToGo + " of " + name + " to " + zone.x + "|" + zone.y);
                                                sent = true;
                                            }
                                        }
                                        else if (heroConfig.clearOasisWithTroop && hero.health >= heroConfig.minHealthWithTroop && hero.available)
                                        {
                                            int troopToGo = Math.Max((def * 10 - hero.fighting) / troop.attack, 50);
                                            if (troopToGo < troopcount)
                                            {
                                                result = TravianApplicationContext.adapter.attack(zone.x, zone.y, troop.id, troopToGo, village.id, true);
                                                zone.status = result;
                                                Util.SerializeArrayList(TravianApplicationContext.villages, "villages.xml");
                                                Console.WriteLine("sent " + troopToGo + " of " + name + " to " + zone.x + "|" + zone.y +" with hero");
                                                sent = true;
                                            }
                                        }
                                    }
                                    info = TravianApplicationContext.adapter.getVillageInfo(village.id);
                                    troopcount = info.getTroopCount(name);
                                    village.current = (village.current + 1) % village.oasis.Count;
                                }
                                Console.WriteLine("Done sending " + name);
                            }
                        }

                    }
                }

                catch (Exception ex)
                {
                    int count1 = TravianApplicationContext.errors.Count;
                    TravianApplicationContext.errors.Add(count1 + " " + ex.Message, ex.ToString());
                    listViewLog.Items.Add(count1 + " " + ex.Message);
                }
            }
            processing = false;
            // reset timer interval to random
            timer1.Interval = Convert.ToInt32(textBoxInterval.Text)*1000;
            Console.WriteLine(timer1.Interval);
        }


        private void doTick() // Old oasis farming
        {
            if (!processing)
            {
                processing = true;
                try
                {
                    // for each village
                    for (int j = 0; j < TravianApplicationContext.villages.Count; j++)
                    {
                        Village village = (Village)TravianApplicationContext.villages[j];
                        TravianApplicationContext.heroInfo = TravianApplicationContext.heroManager.loadHeroInfo();
                        
                        HeroInfo hero = TravianApplicationContext.heroInfo;
                        HeroConfig heroConfig = TravianApplicationContext.heroConfig;
                        // do adventure
                        if (hero.health >= heroConfig.minHealthWithTroop && hero.available && heroConfig.autoAdventure)
                        {
                            bool adventure = TravianApplicationContext.adapter.adventure();
                            if (adventure) hero.available = false;
                        }
                        // solo oasis
                        if (hero.health >= heroConfig.minHealthSolo && hero.available && heroConfig.clearOasisSolo)
                        {
                            ArrayList tmp = village.oasis;
                            village.oasis.Sort(new ZoneComparer());
                            for (int k = 0; k < village.oasis.Count; k++)
                            {
                                Zone zone = (Zone)village.oasis[k];
                                int def = TravianApplicationContext.adapter.getOasisDefend(zone.x, zone.y, false);
                                
                                zone.defend = def;
                                if (def == 0)
                                {
                                    zone.status = "Def " + def + ", pass";
                                }
                                else if (def < hero.fighting / heroConfig.soloFightingTimes)
                                {
                                    String result = TravianApplicationContext.adapter.attack(zone.x, zone.y, 1, 0, village.id, true);
                                    zone.status = result;
                                    Util.SerializeArrayList(TravianApplicationContext.villages, "villages.xml");
                                    if (result.StartsWith("Troop sent"))
                                    {
                                        listViewLog.Items.Add("Solo oasis "+ zone.x + " " + zone.y);
                                        hero.available = false;
                                        break;
                                    }
                                }
                                else
                                {
                                    zone.status = "Oasis defend too strong";
                                }
                            }
                            village.oasis = tmp;
                        }
                        // for each type of troop
                        for (int i = 0; i < village.troops.Count; i++)
                        {
                            Troop troop = (Troop)village.troops[i];
                            int id = troop.id;
                            string name = troop.name;
                            int nEachWave = troop.number_each_wave;
                            int minTroopEachWave = troop.minNumberEachWave;
                            int troopStay = troop.stay;
                            VillageInfo info = TravianApplicationContext.adapter.getVillageInfo(village.id);
                            int troopcount = info.getTroopCount(name);
                            //farm normal
                            if (troop.number_each_wave >= 1)
                            {
                                int count = 0;
                                while (troopcount >= nEachWave && count<200 && info.waves <= village.getNCleanOasis()*troopStay)
                                {
                                    count++;
                                    while (true)
                                    {
                                        try
                                        {
                                            
                                            Console.WriteLine(id + " " + troopcount + " " + village.current +" "+info.waves+" "+village.getNCleanOasis());
                                            if (village.current >= village.oasis.Count) village.current = 0;
                                            if (village.current == 0 && checkBoxAutoShuffle.Checked)
                                            {
                                                village.oasis = Util.Shuffle(village.oasis);
                                            }
                                            Zone zone = (Zone)village.oasis[village.current];
                                            int def = TravianApplicationContext.adapter.getOasisDefend(zone.x, zone.y, TravianApplicationContext.heroConfig.infantry);
                                            zone.defend = def;
                                            String result = "";
                                            if (def == 0)
                                            {
                                                // sending troop in ramdom number
                                                TravianApplicationContext.adapter.selectCity(village.id, name);
                                                Int32 troopToGo = new Random().Next(minTroopEachWave, nEachWave + 1);
                                                result = TravianApplicationContext.adapter.attack(zone.x, zone.y, troop.id, troopToGo, village.id, false);
                                                zone.status = result;
                                                Util.SerializeArrayList(TravianApplicationContext.villages, "villages.xml");
                                            }
                                            else
                                            {
                                                zone.status = "Oasis defend too strong";
                                            }
                                            village.current = (village.current + 1) % village.oasis.Count;
                                            if (result.StartsWith("Troop sent"))
                                            {
                                                break;
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            Console.WriteLine(ex.ToString());
                                        }
                                    }
                                    info = TravianApplicationContext.adapter.getVillageInfo(village.id);
                                    troopcount = info.getTroopCount(name);
                                }
                            }
                            // hero clears oasis with troop
                            else if (troop.number_each_wave == -1 && heroConfig.clearOasisWithTroop && hero.health >= heroConfig.minHealthWithTroop && hero.available)
                            {
                                ArrayList tmp = village.oasis;
                                village.oasis.Sort(new ZoneComparer());
                                for (int k = 0; k < village.oasis.Count; k++)
                                {
                                    Zone zone = (Zone)village.oasis[k];
                                    int def = TravianApplicationContext.adapter.getOasisDefend(zone.x, zone.y, heroConfig.infantry);
                                    zone.defend = def;
                                    if (def == 0)
                                    {
                                        zone.status = "Def " + def + ", pass";
                                    }
                                    else if (def < (troopcount * troop.attack + hero.fighting) / Convert.ToDouble(heroConfig.withTroopFightingTimes))
                                    {
                                        String result = TravianApplicationContext.adapter.attack(zone.x, zone.y, troop.id, troopcount, village.id, true);
                                        zone.status = result;
                                        Util.SerializeArrayList(TravianApplicationContext.villages, "villages.xml");
                                        if (result.StartsWith("Troop sent"))
                                        {
                                            listViewLog.Items.Add("Clear oasis " + zone.x + " " + zone.y);
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        zone.status = "Oasis defend too strong";
                                    }
                                }
                                village.oasis = tmp;
                            }
                            
                            else if (troop.number_each_wave == -2)
                            {
                                while (troopcount > 5500)
                                {
                                    bool r = false;
                                    while (!r)
                                    {
                                        try
                                        {
                                            if (troop.id == 3)
                                            {
                                                //r = TravianApplicationContext.adapter.activateFarmlist(16768, 0, "Imperians");
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            Console.WriteLine(ex.ToString());
                                        }
                                    }
                                    Console.WriteLine("activated farmlist");
                                    troopcount = TravianApplicationContext.adapter.selectCity(village.id, name);
                                }
                            }
                        }

                    }
                }

                catch (Exception ex)
                {
                    int count1 = TravianApplicationContext.errors.Count;
                    TravianApplicationContext.errors.Add(count1 + " " + ex.Message, ex.ToString());
                    listViewLog.Items.Add(count1 + " " + ex.Message);
                }
            }
            processing = false;
            // reset timer interval to random
            timer1.Interval = Convert.ToInt32(textBoxInterval.Text) * 1000;
            Console.WriteLine(timer1.Interval);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //VillageInfo info = TravianApplicationContext.adapter.getVillageInfo("40");
            //MessageBox.Show(info.troops["Clubswingers"].ToString() + " " + info.waves.ToString());
            MessageBox.Show(TravianApplicationContext.adapter.getOasisDefend(17, 18, true).ToString());
            //getOasisMap();
            
            //MessageBox.Show(TravianApplicationContext.adapter.getOasisDefend(-17, 12, false).ToString());
            /*try
            {
                //
                string[] i = new string[] { };
                MessageBox.Show(i[1]);
            }
            catch (Exception ex)
            {
                int count = TravianApplicationContext.errors.Count;
                TravianApplicationContext.errors.Add(count + " " + ex.Message, ex.ToString());
                listViewLog.Items.Add(count + " " + ex.Message);
            }*/
        }

        private void getOasisMap()
        {
            int c = 0;
            for (int ii = -7; ii <= 7; ii++)
                for (int jj = -7; jj <= 7; jj++)
                {
                    int xx = ii * 30 - 15;
                    int yy = jj * 30 - 15;
                    String mapinfo = TravianApplicationContext.adapter.postRequestMapInfo(xx.ToString(), yy.ToString());
                    String pattern = "\"x\":\"(-?\\d+)\",\"y\":\"(-?\\d+)\",\"d\":\\-1,\"c\":\"{k.fo}\"";
                    Regex re = new Regex(pattern);
                    MatchCollection matches = re.Matches(mapinfo);
                    for (int i = 0; i < matches.Count; i++)
                    {
                        int x = Convert.ToInt32(matches[i].Groups[1].Value);
                        int y = Convert.ToInt32(matches[i].Groups[2].Value);
                        Zone zone = new Zone();
                        zone.x = x;
                        zone.y = y;
                        c++;
                        TravianApplicationContext.allOasis.Add(zone);
                        Console.WriteLine(ii + " " + jj + " " + c);
                    }

                }
            Util.SerializeArrayList(TravianApplicationContext.allOasis, "oasis.xml");
        }

        private void buttonFindElephan_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
            buttonFindElephan.Enabled = false;
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            try
            {
                toolStripProgressBar1.Value = e.ProgressPercentage * 100 / TravianApplicationContext.allOasis.Count;
                toolStripStatusLabel1.Text = e.ProgressPercentage + "/" + TravianApplicationContext.allOasis.Count;
            }
            catch (Exception ex)
            {
            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            int x = Convert.ToInt32(textBoxXElephan.Text);
            int y = Convert.ToInt32(textBoxYElephan.Text);
            for (int i = 0; i < TravianApplicationContext.allOasis.Count; i++)
            {
                Zone zone = (Zone)TravianApplicationContext.allOasis[i];
                zone.distance = Math.Sqrt((zone.x - x) * (zone.x - x) + (zone.y - y) * (zone.y - y));
            }
            TravianApplicationContext.allOasis.Sort(new ZoneComparer());
            listViewTarget.Items.Clear();
            for (int i = 0; i < TravianApplicationContext.allOasis.Count; i++)
            {
                Zone zone = (Zone)TravianApplicationContext.allOasis[i];
                Console.WriteLine(i + "/" + TravianApplicationContext.allOasis.Count);
                if (TravianApplicationContext.adapter.has(zone.x, zone.y, "Elephan"))
                {
                    AddListView(new string[] { zone.x.ToString() + "," + zone.y.ToString(), zone.distance.ToString(), zone.status, zone.defend.ToString() });
                }
                backgroundWorker1.ReportProgress(i + 1);
            }
        }

        private void AddListView(string[] items)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.listViewTarget.InvokeRequired)
            {
                AddListViewCallback d = new AddListViewCallback(AddListView);
                this.Invoke(d, new object[] { items });
            }
            else
            {
                listViewTarget.Items.Add(new ListViewItem(items));
            }
        }
        delegate void AddListViewCallback(string[] items);


        private void buttonSort_Click(object sender, EventArgs e)
        {
            int i = comboBoxVillage.SelectedIndex;
            Village village = (Village)TravianApplicationContext.villages[i];

        }

        private void buttonShuffle_Click(object sender, EventArgs e)
        {
            int i = comboBoxVillage.SelectedIndex;
            Village village = (Village)TravianApplicationContext.villages[i];

        }

        private void manageHeroToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (TravianApplicationContext.loggedIn)
            {
                TravianApplicationContext.heroPopup.ShowDialog();
            }
            else
                MessageBox.Show("Must login first");
        }

        private void addVillageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Village village = new Village();
            village.name = comboBoxVillage.Text;

            VillageForm villageForm = new VillageForm(true);
            villageForm.setVillage(village);
            villageForm.Show();
        }

        private void listViewLog_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listViewLog.SelectedItems.Count > 0)
            {
                String message = (string)TravianApplicationContext.errors[listViewLog.SelectedItems[0].Text];
                MessageBox.Show(message);
            }
        }

        private void buttonGetNatar_Click(object sender, EventArgs e)
        {
            String result = TravianApplicationContext.adapter.request(TravianApplicationContext.adapter.server+"spieler.php?uid=1");
            Util.writeStringToFile(result, "natar.html");
            String pattern = "<td class=\"inhabitants\">\\s+(\\d+)\\s+</td>\\s+<td class=\"coords\">\\s+<a class=\"\" href=\"karte\\.php\\?x=(-?\\d+)&amp;y=(-?\\d+)\">";
            Regex re = new Regex(pattern);
            MatchCollection matches = re.Matches(result);
            String linkaddfarm = TravianApplicationContext.adapter.server+"build.php?gid=16&tt=99&action=showSlot&lid=16768&sort=distance&direction=asc";
            int vx = -18;
            int vy = 9;
            ArrayList tmp = new ArrayList();
            for (int i = 0; i < matches.Count; i++)
            {
                int pop = Convert.ToInt32(matches[i].Groups[1].Value);
                int x = Convert.ToInt32(matches[i].Groups[2].Value);
                int y = Convert.ToInt32(matches[i].Groups[3].Value);
                //Console.WriteLine(pop + "," + x + "," + y);
                double dist = Math.Sqrt((vx - x) * (vx - x) + (vy - y) * (vy - y));
                if (dist > 109.4 && dist <= 140 && (x!=0||y!=0))
                {
                        int nTroop = Math.Max(pop / 50, 6);
                        Zone zone = new Zone();
                        zone.x = x;
                        zone.y = y;
                        zone.distance = dist;
                        zone.defend = nTroop;
                        tmp.Add(zone);
                }
            }
            
            tmp.Sort(new ZoneComparer());
            int count = 0;
            for (int i = 0; i < tmp.Count; i++)
            {
                Zone zone = (Zone)tmp[i];
                bool r = false;
                while (!r)
                {
                    r = TravianApplicationContext.adapter.addToFarmList(linkaddfarm, zone.x, zone.y, 3, zone.defend);
                    if (r == false)
                    {
                        Console.WriteLine("false");
                    }
                    else
                    {
                        count += zone.defend;
                        Console.WriteLine(i + " " + zone.distance + " " + zone.defend + " " + zone.x + " " + zone.y + " " + " " + count);
                        if (count > 5000) break;
                    }
                }
            }
            
        }

        private void attackToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            TravianApplicationContext.attackForm.ShowDialog();
        }

        private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                for (int k = 0; k < TravianApplicationContext.oasis.Count;k++ )
                {
                    Zone zone = (Zone)TravianApplicationContext.oasis[k];
                    int def = TravianApplicationContext.adapter.getOasisDefend(zone.x, zone.y, false);
                    zone.defend = def;
                    zone.status = DateTime.Now.ToShortTimeString();
                    if (zone.defend == int.MaxValue)
                    {
                        TravianApplicationContext.oasis.Remove(zone);
                        k--;
                    }
                    //updateListViewTarget(village.oasis);
                }
            }
        }

        private void updateListViewTarget(ArrayList zones)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.listViewTarget.InvokeRequired)
            {
                updateListViewTargetCallback d = new updateListViewTargetCallback(updateListViewTarget);
                this.Invoke(d, new object[] { zones });
            }
            else
            {
                listViewTarget.Items.Clear();
                foreach (Zone zone in zones)
                {
                    listViewTarget.Items.Add(new ListViewItem(new string[] { zone.x.ToString() + "," + zone.y.ToString(), zone.distance.ToString(), zone.status, zone.defend.ToString() }));
                }
            }
        }
        delegate void updateListViewTargetCallback(ArrayList zones);

        private void buttonAddOasis_Click(object sender, EventArgs e)
        {
            int x = Convert.ToInt32(textBoxXElephan.Text);
            int y = Convert.ToInt32(textBoxYElephan.Text);
            for (int i = 0; i < TravianApplicationContext.allOasis.Count; i++)
            {
                Zone zone = (Zone)TravianApplicationContext.allOasis[i];
                zone.distance = Math.Sqrt((zone.x - x) * (zone.x - x) + (zone.y - y) * (zone.y - y));
                zone.defend = int.MaxValue;
                int maxDist = Convert.ToInt32(textBoxMaxDist.Text);
                int minDist = Convert.ToInt32(textBoxMinDist.Text);
                if (zone.distance <= maxDist && zone.distance >= minDist)
                {
                    TravianApplicationContext.oasis.Add(zone);
                }
            }
            TravianApplicationContext.oasis.Sort(new ZoneComparer());
            updateListViewTarget(TravianApplicationContext.oasis);
        }

        private void buttonRefresh_Click(object sender, EventArgs e)
        {
            updateListViewTarget(TravianApplicationContext.oasis);
        }

        private void saveAll()
        {
            Properties.Settings.Default.Save();
            Util.SerializeArrayList(TravianApplicationContext.oasis, "data.xml");
            Util.SerializeArrayList(TravianApplicationContext.farmlists, "farmlists.xml");
            Util.SerializeArrayList(TravianApplicationContext.villages, "villages.xml");
        }

        private void buttonAddFarmList_Click(object sender, EventArgs e)
        {
            string[] tmp = comboBoxTroop.SelectedItem.ToString().Split('_');
            FarmList farmlist = new FarmList();
            farmlist.id = Convert.ToInt32(textBoxFLID.Text);
            farmlist.trooptype = tmp[1];
            farmlist.vid = Convert.ToInt32(textBoxVID.Text);
            farmlist.count = 0;
            TravianApplicationContext.farmlists.Add(farmlist);
            UpdateListViewFarmList(TravianApplicationContext.farmlists);
        }

        private void UpdateListViewFarmList(ArrayList list)
        {
            listViewFarmlist.Items.Clear();
            foreach (FarmList farmlist in list)
            {
                listViewFarmlist.Items.Add(new ListViewItem(new string[] { farmlist.id.ToString(), farmlist.trooptype.ToString(), farmlist.vid.ToString(), farmlist.count.ToString() }));
            }
        }

        private void listViewFarmlist_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listViewFarmlist.SelectedItems.Count > 0)
            {
                TravianApplicationContext.farmlists.Clear();
                listViewFarmlist.SelectedItems[0].Remove();
                for (int i = 0; i < listViewFarmlist.Items.Count; i++)
                {
                    FarmList farmlist = new FarmList();
                    farmlist.id = Convert.ToInt32(Convert.ToInt32(listViewFarmlist.Items[i].SubItems[0].Text));
                    farmlist.trooptype = listViewFarmlist.Items[i].SubItems[1].Text;
                    farmlist.vid = Convert.ToInt32(listViewFarmlist.Items[i].SubItems[2].Text);
                    farmlist.count = Convert.ToInt32(listViewFarmlist.Items[i].SubItems[3].Text);
                    TravianApplicationContext.farmlists.Add(farmlist);
                }
            }
        }

        private void buttonClear_Click(object sender, EventArgs e)
        {
            TravianApplicationContext.oasis.Clear();
            updateListViewTarget(TravianApplicationContext.oasis);
        }

        private void buttonAddToFarmlist_Click(object sender, EventArgs e)
        {

        }

        private void buttonAddNatar_Click(object sender, EventArgs e)
        {
            String result = TravianApplicationContext.adapter.request(TravianApplicationContext.adapter.server+"spieler.php?uid=1");
            Util.writeStringToFile(result, "natar.html");
            String pattern = "<td class=\"inhabitants\">\\s+(\\d+)\\s+</td>\\s+<td class=\"coords\">\\s+<a class=\"\" href=\"karte\\.php\\?x=(-?\\d+)&amp;y=(-?\\d+)\">";
            Regex re = new Regex(pattern);
            MatchCollection matches = re.Matches(result);
            int vx = Convert.ToInt32(textBoxXElephan.Text);
            int vy = Convert.ToInt32(textBoxYElephan.Text);
            int maxdist = Convert.ToInt32(textBoxMaxDist.Text);
            int mindist = Convert.ToInt32(textBoxMinDist.Text);
            for (int i = 0; i < matches.Count; i++)
            {
                int pop = Convert.ToInt32(matches[i].Groups[1].Value);
                int x = Convert.ToInt32(matches[i].Groups[2].Value);
                int y = Convert.ToInt32(matches[i].Groups[3].Value);
                //Console.WriteLine(pop + "," + x + "," + y);
                double dist = Math.Sqrt((vx - x) * (vx - x) + (vy - y) * (vy - y));
                if (dist >= mindist && dist <= maxdist && (x != 0 || y != 0))
                {
                    Zone zone = new Zone();
                    zone.x = x;
                    zone.y = y;
                    zone.distance = dist;
                    zone.defend = pop;
                    TravianApplicationContext.oasis.Add(zone);
                }
            }

            TravianApplicationContext.oasis.Sort(new ZoneComparer());
            updateListViewTarget(TravianApplicationContext.oasis);
        }

        private void buttonImport_Click(object sender, EventArgs e)
        {
            string[] tmp = comboBoxTroopType.SelectedItem.ToString().Split('_');
            int id = Convert.ToInt32(tmp[0]);
            int n = Convert.ToInt32(textBoxTroopNumber.Text);
            for (int i = 0; i < TravianApplicationContext.oasis.Count; i++)
            {
                Zone zone = (Zone)TravianApplicationContext.oasis[i];
                    bool added = false;
                    while (!added)
                    {
                        added = TravianApplicationContext.adapter.addToFarmList(textBoxLinkAddFarm.Text, zone.x, zone.y, id, n);
                        Console.WriteLine(zone.distance);
                    }
                
            }
            MessageBox.Show("Farmlist added");
        }

        private void label9_Click(object sender, EventArgs e)
        {

        }

        private void label10_Click(object sender, EventArgs e)
        {

        }

        private void textBoxPassword_TextChanged(object sender, EventArgs e)
        {

        }

        private void textBoxUsername_TextChanged(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {
            for (int j = 0; j < TravianApplicationContext.villages.Count; j++)
            {
                Village village = (Village)TravianApplicationContext.villages[j];
                    ArrayList tmp = village.oasis;
                    village.oasis.Sort(new ZoneComparer());
                    for (int k = 0; k < village.oasis.Count; k++)
                    {
                        Zone zone = (Zone)village.oasis[k];
                        int def = TravianApplicationContext.adapter.getOasisDefend(zone.x, zone.y, true);

                        zone.defend = def;
                    }
                    village.oasis = tmp;
            }
        }

        private void backgroundWorker3_DoWork(object sender, DoWorkEventArgs e)
        {
            doTick3();
        }

        private void backgroundWorker3_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
        }
    }
}
